package com.monkeyboy.rabbitmq.advanced_features.confirm;

import java.io.IOException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConfirmListener;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class Producer {
	/**
	 * 作用： 消息的确认模式
	 * 
	 * @Author:Gavin
	 * @time:2018年10月30日
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		// 1.创建连接工厂
		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost("localhost");
		connectionFactory.setPort(5672);
		connectionFactory.setVirtualHost("/myproject");
		connectionFactory.setUsername("Gavin");
		connectionFactory.setPassword("123456");
		// 2.获取到连接对象Connection
		Connection connection = connectionFactory.newConnection();

		// 3.通过Connection创建一个新的Channel
		Channel channel = connection.createChannel();

		// 4.制定我们的消息投递模式：消息的确认模式
		channel.confirmSelect();

		String exchangeName = "test_confirm_exchange";
		String routingKey = "confirm.save";
		// 发送一条消息
		channel.basicPublish(exchangeName, routingKey, null, "Hello confirm".getBytes());

		// 添加一个确认监听
		channel.addConfirmListener(new ConfirmListener() {
			// 消息失败发送失败会进入到这个方法
			/**
			 * 业务处理的时候这里就可以处理一些失败的消息后的逻辑,如：日志记录，错误跟踪等
			 *{ deliveryTag:这条消息的唯一标签
			 *  multiple :是否批量
			 *  }
			 */
			

			// 消息发送成功后会进入到这个方法
			@Override
			public void handleAck(long deliveryTag, boolean multiple) throws IOException {
				// TODO Auto-generated method stub
				System.err.println("------- ack -------");
			}	
			
			/**
			 * 在一下这些情况下会走handleNack方法：
			 * 磁盘不够用，队列满了等等。
			 * 
			 * 该模式不能确认消息的100%可靠性传递，有时候可能会出现网络中断导致消息消息的情况，
			 * 这时候需要采用一些定时任务去抓取一些消息重新进行投递。
			 */
			@Override
			public void handleNack(long deliveryTag, boolean multiple) throws IOException {
				// TODO Auto-generated method stub
				System.err.println("------no ack-------");
			}
		});

	}
}
